home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / bc_ti.zip / TI643.ASC < prev    next >
Text File  |  1992-02-25  |  6KB  |  265 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.   PRODUCT  :  Borland C                              NUMBER  :  643
  9.   VERSION  :  All
  10.        OS  :  PC DOS
  11.      DATE  :  February 25, 1992                        PAGE  :  1/4
  12.  
  13.     TITLE  :  Using a Dynamically Allocated Stack in C
  14.  
  15.  
  16.  
  17.  
  18.  
  19.   /*[]------------------------------------------------------------[]*/
  20.   /*|                                                              |*/
  21.   /*|     'Using a LARGE temporary stack in a small program'       |*/
  22.   /*|                                                              |*/
  23.   /*|                                                              |*/
  24.   /*|     Copyright (c) 1991 by Borland International              |*/
  25.   /*|     All Rights Reserved.                                     |*/
  26.   /*|                                                              |*/
  27.   /*[]------------------------------------------------------------[]*/
  28.  
  29.   /************************************************************************
  30.    NOTE:  If you want to use the stack-checking code in Turbo C++ or
  31.           Borland C++ then you must be in the LARGE or HUGE memory model.
  32.    **********************************************************************/
  33.  
  34.   /*
  35.       The theory here is the stack checking option generates the
  36.       following code at the beginning of every function that was compiled
  37.       with it on:
  38.  
  39.       _function proc far
  40.                 push bp
  41.                 mov bp, sp
  42.                 cmp word ptr DGROUP:_stklen, sp
  43.                 ja short @1@74
  44.                 call far ptr F_OVERFLOW@
  45.       @1@74:
  46.                 .    ; the rest of the function...
  47.                 .
  48.                 .
  49.  
  50.  
  51.      This is basically checking SP against the stack length and if SP ever
  52.      becomes greater than _stklen, (which can only happen if you use all
  53.      the stack space and then wrap SP from seg:0000 to seg:FFFE) then the
  54.      overflow function gets called.
  55.  
  56.      All we are doing is allocating a 66K buffer from farmalloc,
  57.      normalizing the pointer to get a full segment, saving the old values
  58.      for ss, sp, and _stklen, setting the new values, and calling the
  59.      stack-hungry function.
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.   PRODUCT  :  Borland C                              NUMBER  :  643
  75.   VERSION  :  All
  76.        OS  :  PC DOS
  77.      DATE  :  February 25, 1992                        PAGE  :  2/4
  78.  
  79.     TITLE  :  Using a Dynamically Allocated Stack in C
  80.  
  81.  
  82.  
  83.  
  84.      This can be very useful for qsort() programs that wish to sort
  85.      very large tables, and don't need 64k of stack all the time.
  86.  
  87.      If you don't use stack checking then you can use this trick from any
  88.      model.
  89.   */
  90.  
  91.  
  92.   #if !defined (__LARGE__)
  93.     #error Must be in the LARGE model!
  94.   #endif
  95.  
  96.  
  97.   #include <dos.h>
  98.   #include <stdio.h>
  99.   #include <stdlib.h>
  100.   #include <alloc.h>
  101.   #include <conio.h>
  102.  
  103.   unsigned _stklen = 2048;     // stack = 2k
  104.  
  105.   unsigned int goober = 0;
  106.   char *p;
  107.  
  108.   void recurse1 (void)
  109.   {
  110.     goober++;
  111.     cprintf ("\rCalling recurse1() %u ", goober);
  112.     recurse1 ();
  113.   }
  114.  
  115.   void do_reg (void)
  116.   {
  117.     recurse1 ();
  118.   }
  119.  
  120.   void do_alloc (void)
  121.   {
  122.   // NOTE: these all MUST be static (or global) because if they were local
  123.   //       the compiler wouldn't be able to access them after we switch
  124.   //       our stacks.
  125.  
  126.     static char far *p;
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.   PRODUCT  :  Borland C                              NUMBER  :  643
  141.   VERSION  :  All
  142.        OS  :  PC DOS
  143.      DATE  :  February 25, 1992                        PAGE  :  3/4
  144.  
  145.     TITLE  :  Using a Dynamically Allocated Stack in C
  146.  
  147.  
  148.  
  149.  
  150.     static unsigned old_ss, old_sp, old_stklen;
  151.  
  152.     if ((p = farmalloc (66000L)) == NULL)
  153.     {
  154.       printf ("\nNo room to allocate stack buffer!\n");
  155.       exit (1);
  156.     }
  157.     /*
  158.      We now have a pointer xxxx:0004. This example will overwrite the
  159.      bottom and top of the segment.  To prevent serious memory
  160.      corruption, we must allocate a full 64K segment and normalize it
  161.      ourselves.  Now if we corrupt memory at xxxx:0000 or xxxx:FFFF we are
  162.      still within the buffer we allocated, and thus are safe.  This
  163.      saves us from incurring the overhead of having a HUGE pointer for
  164.      the address of our buffer.
  165.     */
  166.  
  167.     (long)p += 0x00010000;   // increment segment
  168.     p -= 4;                  // set offset to zero
  169.  
  170.     // p is now = (xxxx + 1):0000
  171.  
  172.     old_ss = _SS;            // save old values
  173.     old_sp = _SP;
  174.     old_stklen = _stklen;
  175.  
  176.     _stklen = 60000U;        // change the stack length (for checking)
  177.  
  178.     _SS = FP_SEG (p);        // set up our new stack segment
  179.  
  180.     _SP = FP_OFF (&(p[_stklen]));  // set the stack to the top
  181.  
  182.     goober = 0;              // reset our counter
  183.     recurse1();              // call the recursive DEATH function
  184.  
  185.      // If we were to get to this point...
  186.  
  187.     _SS = old_ss;            // reset the values
  188.     _SP = old_sp;
  189.     _stklen = old_stklen;
  190.  
  191.     (long)p -= (0x00010000 - 4);
  192.                    // set the pointer back to what it was to free it
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.   PRODUCT  :  Borland C                              NUMBER  :  643
  207.   VERSION  :  All
  208.        OS  :  PC DOS
  209.      DATE  :  February 25, 1992                        PAGE  :  4/4
  210.  
  211.     TITLE  :  Using a Dynamically Allocated Stack in C
  212.  
  213.  
  214.  
  215.  
  216.     free ((void *) p);
  217.   }
  218.  
  219.   int main (void)
  220.   {
  221.     cputs ("\n\rBIG Stack Example (c) 1991 by Borland International\r\n");
  222.    // do_reg();    // call this function to compare with regular stack
  223.     do_alloc ();   // call this one to allocate a BIG temporary stack
  224.     return 0;
  225.   }
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.